/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef ATOMPATH_H
#define ATOMPATH_H

#include <Atom.h>
#include <string>
#include <Converter.h>
#include <vector>

namespace liba
{
namespace animate
{

typedef std::vector<Atom> AtomVector;

/** This class loads path from the sequence of characters, separated by
	reserved "separator" character, which can not be used inside atoms.
	Microsoft Visual Studio 6 has a bug, that does not allow to define
	separator as static const. */
class AtomPath : public AtomVector
{
public:
	enum { separator = '|' };
	AtomPath()
	{}
	AtomPath(const std::string & path)
	{
		assign(path.c_str());
	}
	AtomPath(const char * beg, const char * en)
	{
		assign(beg, en);
	}
	/** @warning This method works slowly. */
	std::string get_str()const;
	void assign(const char * beg, const char * en);
	void assign(const char * str);

	template< class Sym >
	struct ConverterBuffer
	{
		bool convert(const animate::AtomPath & value)
		{
			std::string conv_data = value.get_str();
			return converter::convert( conv_data, &data );
		}
		const Sym * begin()const
		{
			return data.c_str();
		}
		const Sym * end()const
		{
			return data.c_str() + data.size();
		}
	private:
		std::basic_string<Sym> data;
	};

public:
	template<class Sym>
	bool convert(const Sym * be, const Sym * en)
	{
		std::vector<char> buf;
		buf.resize( be - en );
		if( !converter::simple_convert( be, en, &(buf.front()) ) )
			return false;

		assign( std::string( buf.begin(), buf.end() ).c_str() );
		return true;
	}
	bool convert(const char * be, const char * en)
	{
		assign( be, en );
		return true;
	}
};

} // namespace animate

namespace converter
{

template<>
struct ConverterBestCharSelector< animate::AtomPath >
{
	typedef char BestChar;
};

} //namespace converter


} // namespace liba
using namespace liba;

#endif // ATOMPATH_H

